#include <GL/gl.h>
#include <GL/glu.h>
#include <SDL/SDL.h>
#include <iostream>
#include "Game.h"
using namespace std;

Game::Game()
{
	cout << "loading textures...\n";
	textureLoader.loadTextures();
	
	cout << "loading sound...\n";
	sound = new Sound();
	
	cout << "creating emitter...\n";
	cubeEmitter = new CubeEmitter(MAX_EMIT_TIME, CUBES_TO_EMIT);
	
	cout << "creating grid size:" << GRID_SIZE << "...\n";
	for(int i=0; i<GRID_SIZE; i++)
	{
		for(int j=0; j<GRID_SIZE; j++)
		{
			Cube * bottomCube = new Cube(textureLoader.topTextures[0], textureLoader.sideTextures[0]);
			bottomCube->xPos = i * (2 + CUBE_GAP);
			bottomCube->zPos = j * (2 + CUBE_GAP);
			bottomCube->yPos = 0;
			cubePiles[i][j] = new CubePile(bottomCube, sound);
		}
	}
	
	camera = new Camera();
	input.addInputListener(camera);
	
	cursor = new Cursor(cubePiles);
	input.addInputListener(cursor);
}

Game::~Game()
{
	//TODO: delete cubes
	//TODO: delete emitter
	//TODO: delete camera
	//TODO: delete cursor
}

bool Game::events()
{
	SDL_Event event;
	if(SDL_PollEvent(&event))
	{
		switch(event.type)
		{
			case SDL_KEYDOWN : 
				input.key[event.key.keysym.sym ] = true; 
				break;
			case SDL_KEYUP :
				input.key[event.key.keysym.sym ] = false;
				break;
			case SDL_QUIT :
				return false;
				break;
		}
	}
	return true;	
}

void Game::render()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();
	glTranslatef(camera->xPos, camera->yPos, camera->zPos);
	//cout << camera->xPos << " " << camera->yPos << " " << camera->zPos << "\n";
	
	glRotatef(camera->pitch, 1, 0, 0);

	glBlendFunc(GL_SRC_ALPHA, GL_ONE);		// Blending Function For Translucency Based On Source Alpha Value ( NEW )

	glDisable(GL_BLEND);
	for(int x=0; x<GRID_SIZE; x++)
	{
		for(int z=0; z<GRID_SIZE; z++)
		{
			cubePiles[x][z]->render();
		}
	}
	
	
	
//	glEnable(GL_DEPTH_TEST);	// Turn Depth Testing On
//	glDisable(GL_DEPTH_TEST);	// Turn Depth Testing Off
	cursor->render();
/*
	glRotatef(camera->pitch, -1, 0, 0);
	glTranslatef(camera->xPos*-1, camera->yPos*-1, camera->zPos*-1);

	userInterface.render();
	*/
	SDL_GL_SwapBuffers();		
}

void Game::animate(float timeD)
{
	for(int x=0; x<GRID_SIZE; x++)
	{
		for(int z=0; z<GRID_SIZE; z++)
		{
			cubePiles[x][z]->animate(timeD);
		}
	}	
}

void Game::main_loop_function()
{
	try
	{
		int lastTime = SDL_GetTicks();
		while (events())
		{
			int timeNow = SDL_GetTicks();
			float timeD = timeNow - lastTime;
			
			lastTime = timeNow;
			//std::cout << "yPos:" << cubes.at(0)->yPos << " yPos:" << cubes.at(1)->yPos << "\n";

			cubeEmitter->emit(timeD, cubePiles, textureLoader.topTextures, textureLoader.sideTextures);

			
			input.handleInput(timeD);
			animate(timeD);

			render();
		}
	}
	catch(char const* error)
	{
		
	}		
}

void Game::run()
{
	main_loop_function();
}
